﻿//===========================================================================================================================
// Cuberry - http://www.cuberry.net
// Copyright (c) 2012
// by Peacequare® - Amir Moussa
//===========================================================================================================================
// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 
// as published by the Free Software Foundation, either version 3 of the License, or any later version.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// This program is distributed in the hope that it will be useful.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//===========================================================================================================================

using System;
using System.Collections.Generic;
using System.Linq;
using P2.Cuberry.Framework.Helper.Configuration;
using P2.Cuberry.Framework.Helper.DAL;


namespace P2.Cuberry.Framework.Helper.Workflows
{
    public class WorkflowStatus
    {
        public int StatusID { get; set; }
        public int WorkflowID { get; set; }
        public string StatusName { get; set; }

        public int? StatusCategory { get; set; }
        public bool EndStatus { get; set; }
        public string Description { get; set; }
        private static Dictionary<string, List<WorkflowStatus>> statusCache = new Dictionary<string, List<WorkflowStatus>>();
        private static Dictionary<string, Dictionary<int, WorkflowStatus>> statusDictCache = new Dictionary<string, Dictionary<int, WorkflowStatus>>();


        public string StatusNameCur {
            get
            {
                return P2Translator.GetResource(this.StatusName);
            }

        
        }


        string _moduleNameCached = null;
        string _dialogNameCached = null;

        Dictionary<string, WorkflowControl> _disabledControlsCached = null;
        public class WorkflowControl
        {
            public string ControlName { get; set; }
            public bool IsActive { get; set; }
        }


        public Dictionary<string, WorkflowControl> GetWorkflowControls(string ModuleName, string DialogName)
        {
            try
            {
                if (_disabledControlsCached == null || _moduleNameCached == null || _dialogNameCached == null || _moduleNameCached != ModuleName || _dialogNameCached != DialogName)
                {
                    this._disabledControlsCached = new Dictionary<string, WorkflowControl>();
                    this._moduleNameCached = ModuleName;
                    this._dialogNameCached = DialogName;

                    string connectionString = ConfigurationSetUp.GetEntConnectionString("Business", Properties.Settings.Default.EntityResourcesWorkflow);
                    using (WorkflowDataClassesDataContext db = new WorkflowDataClassesDataContext(connectionString))
                    {
                        var wcItems = from wc in db.XConfigWorkflowUIControls
                                      where wc.ModuleName == this._moduleNameCached && wc.DialogName == this._dialogNameCached
                                      && wc.StatusID == this.StatusID
                                      select wc
                                      ;
                        foreach (var wcItem in wcItems)
                        {
                            WorkflowControl wc = new WorkflowControl() { ControlName = wcItem.ControlName, IsActive = wcItem.IsActive.GetValueOrDefault(false) };
                            _disabledControlsCached[wcItem.ControlName] = wc;
                        }
                    }

                }
                return _disabledControlsCached;
            }
            catch (Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", "WorkflowStatus", System.Reflection.MethodInfo.GetCurrentMethod().Name));
                return null;
            }
        }


        public static List<WorkflowStatus> GetStatusListForObject(string EntityName)
        {
            try
            {
                if (statusCache.ContainsKey(EntityName))
                {
                    return statusCache[EntityName];
                }
                else
                {
                    string connectionString = ConfigurationSetUp.GetEntConnectionString("Business", Properties.Settings.Default.EntityResourcesWorkflow);
                    using (WorkflowDataClassesDataContext db = new WorkflowDataClassesDataContext(connectionString))
                    {
                        var statusses = from sts in db.EnterpriseWorkflowStatus
                                        join obj in db.EnterpriseWorkflowObject on sts.WorkflowID equals obj.WorkflowID
                                        where obj.EntityName == EntityName
                                        select new WorkflowStatus
                                        {
                                            StatusID = sts.StatusID,
                                            WorkflowID = sts.WorkflowID,
                                            StatusName = sts.StatusName,
                                            Description = sts.Description,
                                            StatusCategory = sts.StatusCategory,
                                            EndStatus = sts.EndStatus
                                        };
                        List<WorkflowStatus> statussesList = new List<WorkflowStatus>(statusses);
                        statusCache[EntityName] = statussesList;

                        Dictionary<int, WorkflowStatus> statusDict = new Dictionary<int, WorkflowStatus>();
                        foreach (var status in statussesList)
                        {
                            statusDict[status.StatusID] = status;
                        }
                        statusDictCache[EntityName] = statusDict;
                        return statussesList;
                    }
                }
            }
            catch (Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", "WorkflowStatus", System.Reflection.MethodInfo.GetCurrentMethod().Name));
                return null;
            }
        }


        public static List<WorkflowStatus> GetStatusListForModule(string ModuleName)
        {
            try
            {
                string connectionString = ConfigurationSetUp.GetEntConnectionString("Business", Properties.Settings.Default.EntityResourcesWorkflow);
                using (WorkflowDataClassesDataContext db = new WorkflowDataClassesDataContext(connectionString))
                {
                    var statusses = from sts in db.EnterpriseWorkflowStatus
                                    join obj in db.EnterpriseWorkflowObject on sts.WorkflowID equals obj.WorkflowID
                                    where obj.ModuleName == ModuleName
                                    select new WorkflowStatus
                                    {
                                        StatusID = sts.StatusID,
                                        WorkflowID = sts.WorkflowID,
                                        StatusName = sts.StatusName,
                                        Description = sts.Description,
                                        StatusCategory = sts.StatusCategory,
                                        EndStatus = sts.EndStatus
                                    };
                    List<WorkflowStatus> statussesList = new List<WorkflowStatus>(statusses);
                    return statussesList;
                }
            }
            catch (Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", "WorkflowStatus", System.Reflection.MethodInfo.GetCurrentMethod().Name));
                return null;
            }           
        }


        public static WorkflowStatus GetInitialStatus(string ObjectClass)
        {
            WorkflowStatus initStatus = new WorkflowStatus();
            initStatus.StatusID = -1;
            initStatus.StatusName = "New"; 
            return initStatus;
        }


        public static WorkflowStatus GetNoStatus()
        {
            try
            {
                WorkflowStatus initStatus = new WorkflowStatus();
                initStatus.StatusID = 0;
                initStatus.StatusName = "NoStatus"; 
                return initStatus;
            }
            catch (Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", "WorkflowStatus", System.Reflection.MethodInfo.GetCurrentMethod().Name));
                return null;
            }
        }


        public static WorkflowStatus GetItem(string ObjectClass, int StatusID)
        {
            try
            {
                if (!statusDictCache.ContainsKey(ObjectClass))
                    GetStatusListForObject(ObjectClass);
                if (statusDictCache.ContainsKey(ObjectClass))
                {
                    var objectDict = statusDictCache[ObjectClass];
                    if (objectDict.ContainsKey(StatusID))
                    {
                        return objectDict[StatusID];
                    }
                    else if (StatusID == -1)
                    {
                        return GetInitialStatus(ObjectClass);
                    }
                    else
                    {
                        return null;
                    }
                }
                else
                {
                    return null;
                }
            }
            catch (Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", "WorkflowStatus", System.Reflection.MethodInfo.GetCurrentMethod().Name));
                return null;
            }
        }


        public static WorkflowStatus GetItemForModule(string ModuleName, int StatusID)
        {
            try
            {
                if (StatusID == -1)
                {
                    return GetInitialStatus(ModuleName);
                }

                var statusses = GetStatusListForModule(ModuleName);
                var curStatusses = statusses.Where(s => s.StatusID == StatusID);

                foreach (var curStatus in curStatusses)
                {
                    return curStatus;
                }
                return null;
            }
            catch (Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", "WorkflowStatus", System.Reflection.MethodInfo.GetCurrentMethod().Name));
                return null;
            }
        }


    }
}
